home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / test / shiny.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-07  |  8.3 KB  |  308 lines

  1. //
  2. // "$Id: shiny.cxx,v 1.5 1999/01/07 19:18:01 mike Exp $"
  3. //
  4. // OpenGL "shiny buttons" test program for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. #include <config.h>
  27. #include "shiny_panel.cxx"
  28. #include <FL/fl_message.H>
  29. #include <stdio.h>
  30.  
  31. static uchar color[8][3] = {
  32.   {128,136,149},
  33.   {63,54,21},
  34.   {128,136,146},
  35.   {223,223,223},
  36.   {121,128,128},
  37.   {192,206,220},
  38.   {137,143,145},
  39.   {99,81,64}
  40. };
  41. static int thickness = 3;
  42.  
  43. int which = 0;
  44.  
  45. static Fl_Color pcolor;
  46.  
  47. Fl_Window *window;
  48.  
  49. void color_slider_cb(Fl_Value_Slider *o, long i) {
  50.   int v = int(o->value());
  51.   if (!i) {
  52.     color[which][0] = color[which][1] = color[which][2] = v;
  53.     color_slider[1]->value(v);
  54.     color_slider[2]->value(v);
  55.     color_slider[3]->value(v);
  56.   } else {
  57.     color[which][i-1] = v;
  58.   }
  59.   for (int n=0; n<window->children(); n++) window->child(n)->redraw();
  60.   pcolor = FL_BLACK; // make it recalculate actual colors
  61. //   test_box[0]->redraw();
  62. //   test_box[1]->redraw();
  63. //   test_box[2]->redraw();
  64. }
  65.  
  66. void set_sliders() {
  67.   color_slider[0]->value(color[which][0]);
  68.   color_slider[1]->value(color[which][0]);
  69.   color_slider[2]->value(color[which][1]);
  70.   color_slider[3]->value(color[which][2]);
  71. }
  72.  
  73. void thickness_cb(Fl_Slider* s,void*) {
  74.   thickness = int(s->value());
  75.   for (int n=0; n<window->children(); n++) window->child(n)->redraw();
  76. }
  77.  
  78. void which_cb(Fl_Button *, long i) {
  79.   which = which&(~3) | i;
  80.   set_sliders();
  81. }
  82.  
  83. void inside_cb(Fl_Button *b, void*) {
  84.   if (b->value()) which = which | 4;
  85.   else which = which & (3|8);
  86.   set_sliders();
  87. }
  88.  
  89. void dump_cb(Fl_Button *, void*) {
  90.   printf("static uchar color[8][3] = {\n");
  91.   for (int i=0; i<8; i++) {
  92.     printf("  {%d,%d,%d}",color[i][0],color[i][1],color[i][2]);
  93.     if (i<7) printf(",\n");
  94.   }
  95.   printf("\n};\nstatic int thickness = %d;\n",thickness);
  96. }
  97.  
  98. #include <FL/fl_draw.H>
  99.  
  100. #if HAVE_GL
  101. #include <FL/gl.h>
  102.  
  103. static uchar C[8][3]; // actual colors for current button
  104.  
  105. static void calc_color(Fl_Color c) {
  106.   uchar r[3];
  107.   pcolor = c;
  108.   Fl::get_color(c,r[0],r[1],r[2]);
  109.   for (int x = 0; x<8; x++) for (int y=0; y<3; y++) {
  110.     int i = r[y]-166+color[x][y];
  111.     if (i<0) i = 0; else if (i>255) i = 255;
  112.     C[x][y] = i;
  113.   }
  114. }
  115. void shiny_up_box(int x1, int y1, int w1, int h1, Fl_Color c) {
  116.   if (c != pcolor) calc_color(c);
  117.   int x = x1+1;
  118.   int y = Fl_Window::current()->h()-(y1+h1-1);
  119.   int w = w1-2;
  120.   int h = h1-2;
  121.   gl_start();
  122.  
  123.   // left edge:
  124.   glBegin(GL_POLYGON);
  125.   glColor3ub(C[0][0],C[0][1],C[0][2]);
  126.   glVertex2i(x,y);
  127.   glVertex2i(x+thickness,y+thickness);
  128.   glColor3ub(C[3][0],C[3][1],C[3][2]);
  129.   glVertex2i(x+thickness,y+h-thickness);
  130.   glVertex2i(x,y+h);
  131.   glEnd();
  132.  
  133.   // top edge:
  134.   glBegin(GL_POLYGON);
  135.   glVertex2i(x,y+h);
  136.   glVertex2i(x+thickness,y+h-thickness);
  137.   glColor3ub(C[2][0],C[2][1],C[2][2]);
  138.   glVertex2i(x+w-thickness,y+h-thickness);
  139.   glVertex2i(x+w,y+h);
  140.   glEnd();
  141.  
  142.   // right edge:
  143.   glColor3ub(C[1][0],C[1][1],C[1][2]);
  144.   glBegin(GL_POLYGON);
  145.   glVertex2i(x+w-thickness,y+thickness);
  146.   glVertex2i(x+w,y+thickness);
  147.   glVertex2i(x+w,y+h);
  148.   glVertex2i(x+w-thickness,y+h-thickness);
  149.   glEnd();
  150.  
  151.   // bottom edge:
  152.   glBegin(GL_POLYGON);
  153.   glVertex2i(x,y);
  154.   glVertex2i(x+w,y);
  155.   glVertex2i(x+w,y+thickness);
  156.   glVertex2i(x+thickness,y+thickness);
  157.   glEnd();
  158.  
  159.   glBegin(GL_POLYGON);
  160.   glColor3ub(C[4][0],C[4][1],C[4][2]);
  161.   glVertex2i(x+thickness,y+thickness);
  162.   glColor3ub(C[5][0],C[5][1],C[5][2]);
  163.   glVertex2i(x+w-thickness,y+thickness);
  164.   glColor3ub(C[6][0],C[6][1],C[6][2]);
  165.   glVertex2i(x+w-thickness,y+h-thickness);
  166.   glColor3ub(C[7][0],C[7][1],C[7][2]);
  167.   glVertex2i(x+thickness,y+h-thickness);
  168.   glEnd();
  169.  
  170.   gl_finish();
  171.   fl_color(FL_BLACK);
  172.   fl_rect(x1,y1,w1,h1);
  173. }
  174.  
  175. void shiny_down_box(int x1, int y1, int w1, int h1, Fl_Color c) {
  176.   if (c != pcolor) calc_color(c);
  177.   int x = x1+1;
  178.   int y = Fl_Window::current()->h()-(y1+h1-1);
  179.   int w = w1-2;
  180.   int h = h1-2;
  181.   gl_start();
  182.  
  183.   // left edge:
  184.   glColor3ub(C[1][0],C[1][1],C[1][2]);
  185.   glBegin(GL_POLYGON);
  186.   glVertex2i(x,y);
  187.   glVertex2i(x+thickness,y+thickness);
  188.   glVertex2i(x+thickness,y+h-thickness);
  189.   glVertex2i(x,y+h);
  190.   glEnd();
  191.  
  192.   // top edge:
  193.   glBegin(GL_POLYGON);
  194.   glVertex2i(x,y+h);
  195.   glVertex2i(x+thickness,y+h-thickness);
  196.   glVertex2i(x+w-thickness,y+h-thickness);
  197.   glVertex2i(x+w,y+h);
  198.   glEnd();
  199.  
  200.   // bottom edge:
  201.   glBegin(GL_POLYGON);
  202.   glColor3ub(C[0][0],C[0][1],C[0][2]);
  203.   glVertex2i(x+thickness,y+thickness);
  204.   glVertex2i(x,y);
  205.   glColor3ub(C[1][0],C[1][1],C[1][2]);
  206.   glVertex2i(x+w,y);
  207.   glVertex2i(x+w-thickness,y+thickness);
  208.   glEnd();
  209.  
  210.   // right edge:
  211.   glBegin(GL_POLYGON);
  212.   glVertex2i(x+w-thickness,y+thickness);
  213.   glVertex2i(x+w,y);
  214.   glColor3ub(C[2][0],C[2][1],C[2][2]);
  215.   glVertex2i(x+w,y+h);
  216.   glVertex2i(x+w-thickness,y+h-thickness);
  217.   glEnd();
  218.  
  219.   // inside:
  220.   glBegin(GL_POLYGON);
  221.   glColor3ub(C[4][0],C[4][1],C[4][2]);
  222.   glVertex2i(x+thickness,y+thickness);
  223.   glColor3ub(C[5][0],C[5][1],C[5][2]);
  224.   glVertex2i(x+w-thickness,y+thickness);
  225.   glColor3ub(C[6][0],C[6][1],C[6][2]);
  226.   glVertex2i(x+w-thickness,y+h-thickness);
  227.   glColor3ub(C[7][0],C[7][1],C[7][2]);
  228.   glVertex2i(x+thickness,y+h-thickness);
  229.   glEnd();
  230.  
  231.   gl_finish();
  232.   fl_color(FL_BLACK);
  233.   fl_rect(x1,y1,w1,h1);
  234. }
  235.  
  236. // It looks interesting if you use this for the window's boxtype,
  237. // but it is way too slow under MESA:
  238. void shiny_flat_box(int x, int y1, int w, int h, Fl_Color c) {
  239.   if (c != pcolor) calc_color(c);
  240.   int y = Fl_Window::current()->h()-(y1+h);
  241.   gl_start();
  242.   glBegin(GL_POLYGON);
  243.   glColor3ub(C[4][0],C[4][1],C[4][2]);
  244.   glVertex2i(x,y);
  245.   glColor3ub(C[5][0],C[5][1],C[5][2]);
  246.   glVertex2i(x+w,y);
  247.   glColor3ub(C[6][0],C[6][1],C[6][2]);
  248.   glVertex2i(x+w,y+h);
  249.   glColor3ub(C[7][0],C[7][1],C[7][2]);
  250.   glVertex2i(x,y+h);
  251.   glEnd();
  252.   gl_finish();
  253. }
  254. #endif
  255.  
  256. // If you use a shiny box as a background, things like the sliders that
  257. // expect to erase a flat area will not work, as you will see the edges
  258. // of the area.  This "box type" clips to the area and then draws the
  259. // parent's box.  Perhaps sliders should be fixed to do this automatically?
  260. void invisible_box(int x, int y, int w, int h, Fl_Color c) {
  261.   fl_clip(x,y,w,h);
  262.   Fl_Window *W = Fl_Window::current();
  263.   fl_draw_box(W->box(),0,0,W->w(),W->h(),c);
  264.   fl_pop_clip();
  265. }
  266.  
  267. #define SHINY_BOX (Fl_Boxtype)30
  268. #define INVISIBLE_BOX (Fl_Boxtype)31
  269.  
  270. int main(int argc, char **argv) {
  271.   window = make_panels();
  272. #if HAVE_GL
  273.   // This will cause all buttons to be shiny:
  274.   Fl::set_boxtype(FL_UP_BOX, shiny_up_box,3,3,6,6);
  275.   Fl::set_boxtype(FL_DOWN_BOX, shiny_down_box,3,3,6,6);
  276.   // replacing FL_FLAT_BOX does not work!  Fl_Window makes assumptions
  277.   // about what FL_FLAT_BOX does, and sets the X background pixel.
  278. //Fl::set_boxtype(FL_FLAT_BOX, shiny_flat_box, 0,0,0,0);
  279.   // Instead you must change box() on Fl_Window to a different value:
  280.   Fl::set_boxtype(SHINY_BOX, shiny_flat_box, 0,0,0,0);
  281.   window->box(SHINY_BOX);
  282.   Fl::set_boxtype(INVISIBLE_BOX, invisible_box, 0,0,0,0);
  283. #endif
  284.   set_sliders();
  285. //color_slider[0]->box(INVISIBLE_BOX);
  286. //color_slider[1]->box(INVISIBLE_BOX);
  287. //color_slider[2]->box(INVISIBLE_BOX);
  288. //color_slider[3]->box(INVISIBLE_BOX);
  289.   thickness_slider->value(thickness);
  290.   thickness_slider->box(INVISIBLE_BOX);
  291.   thickness_slider->slider(FL_UP_BOX);
  292.   // we must eat the switches first so -display is done before trying
  293.   // to set the visual:
  294.   int i = 0;
  295.   if (Fl::args(argc,argv,i) < argc) Fl::fatal(Fl::help);
  296. #if HAVE_GL
  297.   if (!Fl::gl_visual(FL_RGB)) Fl::fatal("Display does not do OpenGL");
  298. #else
  299.   fl_message("This demo does not work without OpenGL");
  300. #endif
  301.   window->show(argc,argv);
  302.   return Fl::run();
  303. }
  304.  
  305. //
  306. // End of "$Id: shiny.cxx,v 1.5 1999/01/07 19:18:01 mike Exp $".
  307. //
  308.